<?php
Yii::import('ext.file.CFile');

class File extends CFile
{
    public function upload($id, $name)
    {
        if(isset($_FILES[$name])){
            if($uploaded=$this->set($name)){
                $dir=new Directories;
                $newFile=$dir->findByPk($id)->path.DIRECTORY_SEPARATOR.$uploaded->basename;
                if(is_file($newFile)){
                    return false;
                }
                $newFile=$uploaded->copy($newFile);
                if($newFile){
                    $file=new Files;
                    $file->attributes=array(
                        'file_dir_id'=>$id,
                        'file_name'=>$newFile->filename,
                        'file_exp'=>$newFile->extension,
                        'file_src'=>$dir->findByPk($id)->src.DIRECTORY_SEPARATOR.$newFile->filename.'.'.$newFile->extension,
                    );
                    if($file->save()){
                        return true;
                    }
                }
            }
        }

        return false;
    }

    public function create($id, $name)
    {
        $dir=new Directories;

        if(isset($_POST[$name]['name'])){
            $newDir=$dir->findByPk($id)->path.DIRECTORY_SEPARATOR.$_POST[$name]['name'];

            if(!is_dir($newDir) && $this->mkDir($id, $_POST[$name]['name'])){
                return true;
            }
        }

        return false;
    }

    public function dirUpdate($id, $name)
    {
        if(isset($_POST[$name]['name'])){
            $dir=new Directories;
            $dir=$dir->findByPk($id);
            $oldPath=$dir->path;
            $children=$dir->children;
            $newName=$_POST[$name]['name'];
            $dir->dir_name=$newName;
            $dir->dir_path=$dir->root.DIRECTORY_SEPARATOR.$newName;
            $dir->old_path=$oldPath;

            if($dir->save()){
                if($children){
                    foreach($children as $child){
                        $child->dir_root=$dir->path;
                        $child->dir_path=$dir->path.DIRECTORY_SEPARATOR.$child->name;
                        $child->save();
                    }
                }

                return $dir;
            }
        }

        return false;
    }

    public function fileUpdate($id, $name)
    {
        if(isset($_POST[$name]['name'])){
            $newName=$_POST[$name]['name'];
            $file=new Files;
            $file=$file->findByPk($id);
            $file->oldName=$file->path.DIRECTORY_SEPARATOR.$file->fileName;
            $file->file_src=str_replace($file->name, $newName, $file->src);
            $file->file_name=$newName;

            if($file->save()){
                return true;
            }
        }

        return false;
    }

    public function delete($names=array())
    {
        $result=false;
        list($name1, $name2)=$names;

        if(isset($_POST[$name1])){
            foreach($_POST[$name1] as $dir){
                if($dir['delete'] && $this->rmDir($dir['id'])){
                    $result=true;
                }
            }
        }

        if(isset($_POST[$name2])){
            foreach($_POST[$name2] as $file){
                if($file['delete'] && $this->rmFiles(false, $file['id'])){
                    $result=true;
                }
            }
        }

        return $result;
    }

    public function rmDir($id)
    {
        $result=false;
        $dir=new Directories;
        $dir=$dir->findByPk($id);
        $children=$dir->children;

        if($children){
            foreach($children as $child){
                $result=$this->rmDir($child->id) ? true : $result;
            }
        }

        $result=$this->deleteDir($dir) ? true : $result;

        return $result;
    }

    public function rmFiles($dir, $id=false)
    {
        $result=false;
        $file=new Files;
        $files=$id ? array($file->findByPk($id)) : $dir->files;
        if($files){
            foreach($files as $file){
                $file->oldFile=$file->path.DIRECTORY_SEPARATOR.$file->fileName;
                if($file->delete()){
                    $result=true;
                }
            }
        }

        return $result;
    }

    public function copy(){
        if(isset($_POST['Directories']) || isset($_POST['Files'])){
            session_start();
            $_SESSION['copy']=$_POST;
        }
    }

    public function paste($id, $names=array())
    {
        $result=false;
        if(isset($_POST['paste'])){
            list($name1, $name2)=$names;
            if(isset($_SESSION['copy'][$name1]) && $_SESSION['copy'][$name1]){
                foreach($_SESSION['copy'][$name1] as $num=>$dir){
                    if($dir['delete'] && $this->pasteDir($id, $dir['id'])){
                        $_SESSION['tmpCopy'][$name1][]=$dir;
                        unset($_SESSION['copy'][$name1][$num]);
                        $result=true;
                    }
                }
            }
            if(isset($_SESSION['copy'][$name2]) && $_SESSION['copy'][$name2]){
                foreach($_SESSION['copy'][$name2] as $num=>$file){
                    if($file['delete'] && $this->pasteFile($id, $file['id'], $name2)){
                        $_SESSION['tmpCopy'][$name2][]=$file;
                        unset($_SESSION['copy'][$name2][$num]);
                        $result=true;
                    }
                }
            }

            unset($_SESSION['copy']['all'], $_SESSION['copy']['param'], $_SESSION['copy']['fileId'], $_SESSION['copy']['dirId']);
            $_SESSION['copy']=$_SESSION['tmpCopy'];
            unset($_SESSION['tmpCopy']);
            Yii::app()->request->redirect(Yii::app()->createUrl('directories/index', array('id'=>$id)));
        }
        return $result;
    }

    protected function pasteDir($targetId=1, $sourceId)
    {
        $dir=new Directories;
        $source=$dir->findByPk($sourceId);

        if($newDir=$this->mkDir($targetId, $source->name, $sourceId)){
            foreach($source->files as $file){
                $this->pasteFile($newDir->id, $file->id);
            }
            $result=true;
        }else{
            return false;
        }

        if($children=$source->children){
            foreach($children as $child){
                if($this->pasteDir($newDir->id, $child->id)){
                    $result=true;
                }
            }
        }

        return $result;
    }

    protected function pasteFile($dirId=1, $fileId, $name='Files')
    {
        $dir=new Directories;
        $newFile=new Files;
        $file=$newFile->findByPk($fileId);
        $fileName=DIRECTORY_SEPARATOR.$file->fileName;

        $newFile->attributes=array(
            'oldFile'=>$file->path.$fileName,
            'file_name'=>$file->name,
            'file_exp'=>$file->exp,
            'file_dir_id'=>$dirId,
            'file_src'=>$dir->findByPk($dirId)->src.DIRECTORY_SEPARATOR.$file->name.'.'.$file->exp,
        );

        if(is_file($newFile->path.$fileName)){
            if($paste=$this->pasteOptions()){
                $oldFile=$newFile->findByAttributes(array('file_dir_id'=>$dirId, 'file_name'=>$file->name, 'file_exp'=>$file->exp));
                $newName=isset($_POST[$name]['name']) ? $_POST[$name]['name'] : time();
                switch($paste){
                    case 'replace':
                        if($newName!=$newFile->name){
                            $newFile->file_name=$newName;
                            $newFile->file_src=str_replace($file->name, $newName, $newFile->src);
                        }else{
                            return false;
                        }
                        break;
                    case 'remove':
                        if(!$this->rmFiles(false, $oldFile->id)){
                            return false;
                        }
                        break;
                    case 'skip':
                        return true;
                        break;
                }
            }else{
                $_SESSION['copy']['fileId']=$fileId;
                Yii::app()->request->redirect(Yii::app()->createUrl('directories/paste', array(
                    'id'=>$dirId,
                )));
            }
        }

        return $newFile->save();
    }

    protected function mkDir($id, $name, $dirId=1)
    {
        $newDir=new Directories;
        $currentDir=$newDir->findByPk($id);
        $dir=$currentDir->path.DIRECTORY_SEPARATOR.$name;

        if(is_dir($dir)){
            if($paste=$this->pasteOptions()){
                $oldDir=$newDir->findByAttributes(array('dir_root_id'=>$id, 'dir_name'=>$name));
                switch($paste){
                    case 'replace':
                        return $newDir->findByAttributes(array('dir_root_id'=>$id, 'dir_name'=>$name));
                        break;
                    case 'remove':
                        if(!$this->rmDir($oldDir->id)){
                            return false;
                        }
                        break;
                    case 'skip':
                        return false;
                        break;
                }
            }else{
                $_SESSION['copy']['dirId']=$dirId;
                Yii::app()->request->redirect(Yii::app()->createUrl('directories/paste', array(
                    'id'=>$id,
                )));
            }
        }

        $newDir->attributes=array(
            'dir_name'=>$name,
            'dir_path'=>$dir,
            'dir_root'=>$currentDir->path,
            'dir_root_id'=>$id,
        );

        if($newDir->save()){
            return $newDir;
        }

        return false;
    }

    protected function deleteDir($dir)
    {
        $result=$this->rmFiles($dir) ? true : false;
        return $dir->delete() ? true : $result;
    }

    protected function pasteOptions()
    {
        $paste=false;
        if(isset($_SESSION['copy']['all'])){
            $paste=$_SESSION['copy']['all'];
        }elseif(isset($_SESSION['copy']['param'])){
            $paste=$_SESSION['copy']['param']['paste'];
            if($_SESSION['copy']['param']['all']){
                $_SESSION['copy']['all']=$paste;
            }
            unset($_SESSION['copy']['param']);
        }
        return $paste;
    }
}